using System;
using System.Runtime.Serialization;

namespace TrueCode.Core
{
	[Serializable]
// ReSharper disable UnusedTypeParameter
	public class Exception< T > : Exception
// ReSharper restore UnusedTypeParameter
	{
		public int Id{ get; private set; }

		public Exception() { }
		public Exception( string message) : base(message) { }
		public Exception( string formatMessage, params object[] args) : base(String.Format(formatMessage, args)) { }
		public Exception( Exception innerException, string message) : base(message, innerException) { }
		public Exception( Exception innerException, String formatMessage, params Object[] args) : base(String.Format(formatMessage, args), innerException) { }
		public Exception( Exception innerException) : base(innerException.Message, innerException) { }

		public Exception(int id){Id = id;}
		public Exception(int id, string message) : base(message){Id = id;}
		public Exception(int id, string formatMessage, params object[] args ) : base( String.Format( formatMessage, args ) ){Id = id;}
		public Exception(int id, Exception innerException, string message) : base(message, innerException){Id = id;}
		public Exception(int id, Exception innerException, String formatMessage, params Object[] args ) : base( String.Format( formatMessage, args ), innerException ){Id = id;}
		public Exception(int id, Exception innerException) : base(innerException.Message, innerException){Id = id;}
		protected Exception( SerializationInfo info, StreamingContext context ) : base( info, context ){}
	}

	[Serializable]
// ReSharper disable UnusedTypeParameter
	public class Exception<T, TSpecialization > : Exception< T >
// ReSharper restore UnusedTypeParameter
	{
		public Exception() {}

		public Exception(string message) : base(message) {}
		public Exception(string formatMessage, params object[] args) : base(formatMessage, args) {}
		public Exception(Exception innerException, string message) : base(innerException, message) {}
		public Exception(Exception innerException, string formatMessage, params object[] args) : base(innerException, formatMessage, args) {}
		public Exception(Exception innerException) : base(innerException) {}

		public Exception(int id) : base(id) {}
		public Exception(int id, string message) : base(id, message) {}
		public Exception(int id, string formatMessage, params object[] args) : base(id, formatMessage, args) {}
		public Exception(int id, Exception innerException, string message) : base(id, innerException, message) {}
		public Exception(int id, Exception innerException, string formatMessage, params object[] args) : base(id, innerException, formatMessage, args) {}
		public Exception(int id, Exception innerException) : base(id, innerException) {}
		protected Exception(SerializationInfo info, StreamingContext context) : base(info, context) {}
	}

//	[Serializable]
//	public class Exception< T, TInnerException > : Exception< T > where TInnerException : Exception, new()
//	{
////		new public TInnerException InnerException
////		{
////			get{ return ( TInnerException )base.InnerException; }
////		}
//
//		public Exception() {}
//
//		public Exception(TInnerException innerException, String formatMessage, params Object[] args) : base(innerException, String.Format(formatMessage, args)) {}
//		public Exception(TInnerException innerException, string message) : base(innerException, message) { }
//		public Exception(TInnerException innerException) : base(innerException, innerException.Message) { }
//
//		public Exception(int id, TInnerException innerException, String formatMessage, params Object[] args) : base(id, innerException, String.Format(formatMessage, args)) { }
//		public Exception(int id, TInnerException innerException, string message) : base(id, innerException, message) { }
//		public Exception(int id, TInnerException innerException) : base(id, innerException, innerException.Message) { }
//		protected Exception( SerializationInfo info, StreamingContext context ) : base( info, context ){}
//	}
}
